import { useSettingsStore } from '@/store';
import { useRef, useCallback } from 'react';
import { name } from '@/package.json';
import { toast } from 'sonner';

export enum TaskType {
  'collect',
  'process',
  'push',
  'push-video',
}

export interface TaskInfo {
  skuIdInfo: string;
  gigaProductId: string;
  gigaSku: string;
  taskType: TaskType;
  available?: number;
  force?: boolean;
}

interface TaskItem {
  (): Promise<any>;
  extraData: TaskInfo;
}

export interface Task {
  task: TaskItem;
  resolve?: (result: any) => void;
  reject?: (error: any) => void;
}

// 是否是重复任务
export function isRepeatTask(totalTask: Task[], newTaskItem: TaskItem) {
  const { skuIdInfo, taskType } = newTaskItem.extraData;
  // 货号和操作类型相同时才认为是重复任务
  return totalTask.some(
    (task) =>
      task.task.extraData.skuIdInfo === skuIdInfo && task.task.extraData.taskType === taskType,
  );
}
export function useConcurrentRequest(restoreKey?: string) {
  const queue = useRef<Task[]>([]);
  const activeTask = useRef<Task[]>([]);
  const totalTask = useRef<Task[]>([]);
  const completedTask = useRef<Task[]>([]);
  const isStop = useRef(false);
  const taskConcurrencyLimit = useSettingsStore(
    (state) => state.batchSettings.taskConcurrencyLimit,
  );
  const taskConcurrencyLimitRef = useRef(taskConcurrencyLimit);

  const processQueue = useCallback(() => {
    // console.log(queue);
    // 当队列为空或达到并发限制时停止处理
    if (
      activeTask.current.length >= taskConcurrencyLimitRef.current ||
      queue.current.length === 0 ||
      isStop.current
    )
      return;

    // 从队列中取出下一个任务
    const nextTask = queue.current.shift();

    if (nextTask) {
      activeTask.current.push(nextTask);
      // 执行任务
      const taskPromise = nextTask.task();

      taskPromise
        .then(nextTask.resolve)
        .catch(nextTask.reject)
        .finally(() => {
          activeTask.current = activeTask.current.filter((task) => task !== nextTask);
          completedTask.current.push(nextTask);
          processQueue(); // 处理下一个任务
        });
    }
  }, []);

  useEffect(() => {
    taskConcurrencyLimitRef.current = taskConcurrencyLimit;
    const count = taskConcurrencyLimitRef.current - activeTask.current.length;
    for (let i = 0; i < count; i++) {
      processQueue();
    }
  }, [taskConcurrencyLimit, processQueue]);

  const resume = useCallback(() => {
    isStop.current = false;
    const count = taskConcurrencyLimitRef.current - activeTask.current.length;
    for (let i = 0; i < count; i++) {
      processQueue();
    }
  }, [processQueue]);

  const clearQueue = useCallback(function clearQueue() {
    // 在 totalTask 队列中移除 queue 相关的任务
    totalTask.current = totalTask.current.filter((item) => {
      return !queue.current.some((task) => task === item);
    });

    queue.current = [];
  }, []);

  const enqueueTask = useCallback(
    (task: Task['task']) => {
      return new Promise((resolve, reject) => {
        const newTask = { task, resolve, reject };
        // 如果是重复任何立即返回 resolve 任务完成,这个任务不会计入任何的统计
        if (isRepeatTask(totalTask.current, task)) {
          resolve(void 0);
          return;
        }

        totalTask.current.push(newTask);

        queue.current.push(newTask);
        processQueue();
      });
    },
    [processQueue],
  );

  // 持久化处理
  useEffect(() => {
    function handleBeforeUnload(event: BeforeUnloadEvent) {
      if (!restoreKey) {
        return;
      }
      const restQueue = activeTask.current.concat(queue.current);
      const collectInfos = restQueue.map((task) => task.task.extraData);
      try {
        localStorage.setItem(restoreKey, JSON.stringify(collectInfos));
      } catch (error) {
        toast.error(`localStorage 存储已经到达上限`);
      }
    }
    window.addEventListener('beforeunload', handleBeforeUnload);

    // 每隔 3 秒记录正在处理和待处理的任务,避免浏览器崩溃后无法恢复
    const timmer = setInterval(handleBeforeUnload, 3000);
    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
      clearInterval(timmer);
    };
  }, []);

  return {
    enqueueTask,
    queue,
    totalTask,
    activeTask,
    completedTask,
    isStop,
    resume,
    clearQueue,
  };
}
